/*     */ package com.zimbra.cs.account.accesscontrol;
/*     */ 
/*     */ import com.google.common.annotations.VisibleForTesting;
/*     */ import com.google.common.cache.Cache;
/*     */ import com.google.common.cache.CacheBuilder;
/*     */ import com.zimbra.common.localconfig.KnownKey;
/*     */ import com.zimbra.common.localconfig.LC;
/*     */ import com.zimbra.common.service.ServiceException;
/*     */ import com.zimbra.common.util.Log;
/*     */ import com.zimbra.common.util.ZimbraLog;
/*     */ import com.zimbra.cs.account.Account;
/*     */ import com.zimbra.cs.account.DistributionList;
/*     */ import com.zimbra.cs.account.Domain;
/*     */ import com.zimbra.cs.account.DynamicGroup;
/*     */ import com.zimbra.cs.account.NamedEntry;
/*     */ import com.zimbra.cs.account.Provisioning;
/*     */ import com.zimbra.cs.account.Provisioning.GroupMembership;
/*     */ import java.util.HashSet;
/*     */ import java.util.Set;
/*     */ import java.util.concurrent.Callable;
/*     */ import java.util.concurrent.ExecutionException;
/*     */ import java.util.concurrent.TimeUnit;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public abstract class RightBearer
/*     */ {
/*     */   protected NamedEntry mRightBearer;
/*     */   
/*     */   static RightBearer newRightBearer(NamedEntry entry)
/*     */     throws ServiceException
/*     */   {
/*  45 */     if (((entry instanceof Account)) && (AccessControlUtil.isGlobalAdmin((Account)entry, true))) {
/*  46 */       return new GlobalAdmin(entry, null);
/*     */     }
/*  48 */     return Grantee.getGrantee(entry);
/*     */   }
/*     */   
/*     */   protected RightBearer(NamedEntry grantee)
/*     */   {
/*  53 */     this.mRightBearer = grantee;
/*     */   }
/*     */   
/*     */   String getId() {
/*  57 */     return this.mRightBearer.getId();
/*     */   }
/*     */   
/*     */   String getName() {
/*  61 */     return this.mRightBearer.getName();
/*     */   }
/*     */   
/*     */   static class GlobalAdmin extends RightBearer {
/*     */     private GlobalAdmin(NamedEntry grantee) throws ServiceException {
/*  66 */       super();
/*     */     }
/*     */   }
/*     */   
/*     */   @VisibleForTesting
/*     */   public static class Grantee extends RightBearer {
/*     */     GranteeType mGranteeType;
/*     */     Domain mGranteeDomain;
/*     */     Set<String> mIdAndGroupIds;
/*     */     private static final Cache<GranteeCacheKey, Grantee> GRANTEE_CACHE;
/*     */     private static final long MAX_CACHE_EXPIRY = 1800000L;
/*     */     
/*     */     @VisibleForTesting
/*  79 */     public Grantee(NamedEntry grantee) throws ServiceException { this(grantee, (Set)null, true); }
/*     */     
/*     */     protected Grantee(NamedEntry grantee, boolean adminOnly) throws ServiceException
/*     */     {
/*  83 */       this(grantee, (Set)null, adminOnly);
/*     */     }
/*     */     
/*     */     protected Grantee(NamedEntry grantee, Set<Right> rights, boolean adminOnly) throws ServiceException {
/*  87 */       super();
/*     */       
/*  89 */       Provisioning prov = grantee.getProvisioning();
/*  90 */       Provisioning.GroupMembership granteeGroups = null;
/*     */       
/*  92 */       if ((grantee instanceof Account)) {
/*  93 */         this.mGranteeType = GranteeType.GT_USER;
/*  94 */         this.mGranteeDomain = prov.getDomain((Account)grantee);
/*  95 */         granteeGroups = prov.getGroupMembershipWithRights((Account)grantee, rights, adminOnly);
/*     */       }
/*  97 */       else if ((grantee instanceof DistributionList)) {
/*  98 */         this.mGranteeType = GranteeType.GT_GROUP;
/*  99 */         this.mGranteeDomain = prov.getDomain((DistributionList)grantee);
/* 100 */         granteeGroups = prov.getGroupMembership((DistributionList)grantee, adminOnly);
/*     */       }
/* 102 */       else if ((grantee instanceof DynamicGroup)) {
/* 103 */         this.mGranteeType = GranteeType.GT_GROUP;
/* 104 */         this.mGranteeDomain = prov.getDomain((DynamicGroup)grantee);
/*     */ 
/*     */       }
/*     */       else
/*     */       {
/*     */ 
/* 110 */         if (adminOnly) {
/* 111 */           throw ServiceException.INVALID_REQUEST("invalid grantee type", null);
/*     */         }
/* 113 */         if ((grantee instanceof Domain)) {
/* 114 */           this.mGranteeType = GranteeType.GT_DOMAIN;
/* 115 */           this.mGranteeDomain = ((Domain)grantee);
/*     */         }
/*     */       }
/*     */       
/*     */ 
/* 120 */       if ((adminOnly) && 
/* 121 */         (!RightBearer.isValidGranteeForAdminRights(this.mGranteeType, grantee))) {
/* 122 */         throw ServiceException.INVALID_REQUEST("invalid grantee", null);
/*     */       }
/*     */       
/*     */ 
/* 126 */       if (this.mGranteeDomain == null) {
/* 127 */         throw ServiceException.FAILURE("internal error, cannot get domain for grantee", null);
/*     */       }
/*     */       
/*     */ 
/* 131 */       this.mIdAndGroupIds = new HashSet();
/* 132 */       this.mIdAndGroupIds.add(grantee.getId());
/* 133 */       if (granteeGroups != null) {
/* 134 */         this.mIdAndGroupIds.addAll(granteeGroups.groupIds());
/*     */       }
/*     */     }
/*     */     
/*     */     protected static Grantee getGrantee(NamedEntry namedEntry) throws ServiceException {
/* 139 */       return getGrantee(namedEntry, (Set)null, true);
/*     */     }
/*     */     
/*     */     protected static Grantee getGrantee(NamedEntry namedEntry, boolean adminOnly) throws ServiceException {
/* 143 */       return getGrantee(namedEntry, (Set)null, adminOnly);
/*     */     }
/*     */     
/*     */     private static Grantee getGranteeFromCache(NamedEntry namedEntry, Set<Right> right, boolean adminOnly) throws ServiceException
/*     */     {
/* 148 */       Grantee grntee = null;
/* 149 */       GranteeCacheKey key = new GranteeCacheKey(namedEntry, right, adminOnly, null);
/*     */       try {
/* 151 */         grntee = (Grantee)GRANTEE_CACHE.get(key, new Callable()
/*     */         {
/*     */           public RightBearer.Grantee call() throws ServiceException {
/* 154 */             return new RightBearer.Grantee(this.val$key.namedEntry, this.val$key.rights, this.val$key.adminOnly);
/*     */           }
/*     */         });
/*     */       } catch (ExecutionException e) {
/* 158 */         Throwable throwable = e.getCause();
/* 159 */         if ((throwable != null) && ((throwable instanceof ServiceException))) {
/* 160 */           throw ((ServiceException)throwable);
/*     */         }
/* 162 */         ZimbraLog.acl.debug("Unexpected escape getting from GRANTEE_CACHE", e);
/*     */       }
/* 164 */       return grntee;
/*     */     }
/*     */     
/*     */     protected static Grantee getGrantee(NamedEntry namedEntry, Set<Right> right, boolean adminOnly) throws ServiceException
/*     */     {
/* 169 */       if (null == GRANTEE_CACHE) {
/* 170 */         return new Grantee(namedEntry, right, adminOnly);
/*     */       }
/* 172 */       return getGranteeFromCache(namedEntry, right, adminOnly);
/*     */     }
/*     */     
/*     */     boolean isAccount()
/*     */     {
/* 177 */       return this.mGranteeType == GranteeType.GT_USER;
/*     */     }
/*     */     
/*     */     Account getAccount() throws ServiceException {
/* 181 */       if (this.mGranteeType != GranteeType.GT_USER) {
/* 182 */         throw ServiceException.FAILURE("internal error", null);
/*     */       }
/* 184 */       return (Account)this.mRightBearer;
/*     */     }
/*     */     
/*     */     Domain getDomain() {
/* 188 */       return this.mGranteeDomain;
/*     */     }
/*     */     
/*     */     Set<String> getIdAndGroupIds() {
/* 192 */       return this.mIdAndGroupIds;
/*     */     }
/*     */     
/*     */ 
/*     */ 
/*     */     static
/*     */     {
/* 199 */       long granteeCacheSize = 0L;
/* 200 */       long granteeCacheExpireAfterMillis = 0L;
/* 201 */       granteeCacheSize = LC.short_term_grantee_cache_size.longValue();
/* 202 */       if (granteeCacheSize > 0L) {
/* 203 */         granteeCacheExpireAfterMillis = LC.short_term_grantee_cache_expiration.longValue();
/* 204 */         if (granteeCacheExpireAfterMillis < 0L) {
/* 205 */           granteeCacheExpireAfterMillis = 0L;
/* 206 */           granteeCacheSize = 0L;
/* 207 */         } else if (granteeCacheExpireAfterMillis > 1800000L) {
/* 208 */           granteeCacheExpireAfterMillis = 1800000L;
/*     */         }
/*     */       }
/* 211 */       if (granteeCacheSize > 0L) {
/* 212 */         GRANTEE_CACHE = CacheBuilder.newBuilder().maximumSize(granteeCacheSize).expireAfterWrite(granteeCacheExpireAfterMillis, TimeUnit.MILLISECONDS).build();
/*     */         
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/* 218 */         ZimbraLog.acl.trace("RightBearer GRANTEE_CACHE BUILD size=%d expire=%dms", new Object[] { Long.valueOf(granteeCacheSize), Long.valueOf(granteeCacheExpireAfterMillis) });
/*     */       }
/*     */       else {
/* 221 */         GRANTEE_CACHE = null;
/*     */       }
/*     */     }
/*     */     
/*     */     public static void clearGranteeCache() {
/* 226 */       if (null != GRANTEE_CACHE) {
/* 227 */         ZimbraLog.acl.debug("Clearing short term grantee cache of %d items.", new Object[] { Long.valueOf(GRANTEE_CACHE.size()) });
/* 228 */         GRANTEE_CACHE.invalidateAll();
/*     */       }
/*     */     }
/*     */     
/*     */     private static final class GranteeCacheKey {
/*     */       private final NamedEntry namedEntry;
/*     */       private final Set<Right> rights;
/*     */       private final boolean adminOnly;
/*     */       
/* 237 */       private GranteeCacheKey(NamedEntry namedEntry, Set<Right> rights, boolean adminOnly) { this.namedEntry = namedEntry;
/* 238 */         this.rights = rights;
/* 239 */         this.adminOnly = adminOnly;
/*     */       }
/*     */       
/*     */       public boolean equals(Object other)
/*     */       {
/* 244 */         if (!(other instanceof GranteeCacheKey)) {
/* 245 */           return false;
/*     */         }
/* 247 */         GranteeCacheKey ogck = (GranteeCacheKey)other;
/* 248 */         if (this.adminOnly != ogck.adminOnly) {
/* 249 */           return false;
/*     */         }
/* 251 */         if (!this.namedEntry.getName().equals(ogck.namedEntry.getName())) {
/* 252 */           return false;
/*     */         }
/* 254 */         if (this.rights == null) {
/* 255 */           return ogck.rights == null;
/*     */         }
/* 257 */         return this.rights.equals(ogck.rights);
/*     */       }
/*     */       
/*     */ 
/*     */       public int hashCode()
/*     */       {
/* 263 */         int code = this.namedEntry.getName().hashCode() + Boolean.valueOf(this.adminOnly).hashCode();
/* 264 */         if (this.rights != null) {
/* 265 */           code += this.rights.hashCode();
/*     */         }
/* 267 */         return code;
/*     */       }
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   static boolean isValidGranteeForAdminRights(GranteeType gt, NamedEntry grantee)
/*     */   {
/* 283 */     if (gt == GranteeType.GT_USER) {
/* 284 */       return (!grantee.getBooleanAttr("zimbraIsAdminAccount", false)) && (grantee.getBooleanAttr("zimbraIsDelegatedAdminAccount", false));
/*     */     }
/* 286 */     if (gt == GranteeType.GT_GROUP)
/* 287 */       return grantee.getBooleanAttr("zimbraIsAdminGroup", false);
/* 288 */     if (gt == GranteeType.GT_EXT_GROUP) {
/* 289 */       return true;
/*     */     }
/* 291 */     return false;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */   static boolean matchesGrantee(Grantee grantee, ZimbraACE ace)
/*     */     throws ServiceException
/*     */   {
/* 299 */     Set<String> granteeIds = grantee.getIdAndGroupIds();
/* 300 */     if (granteeIds.contains(ace.getGrantee()))
/* 301 */       return true;
/* 302 */     if (ace.getGranteeType() == GranteeType.GT_EXT_GROUP) {
/* 303 */       if (grantee.isAccount()) {
/* 304 */         return ace.matchesGrantee(grantee.getAccount(), true);
/*     */       }
/*     */       
/*     */ 
/* 308 */       throw ServiceException.FAILURE("Not yet implemented", null);
/*     */     }
/*     */     
/* 311 */     return false;
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/account/accesscontrol/RightBearer.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */